package com.fjec.devops.service.impl;

import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fjec.common.Const;
import com.fjec.common.enums.EnumSysCode;
import com.fjec.common.exception.BizException;
import com.fjec.common.jxls.DataFour;
import com.fjec.common.jxls.DataSix;
import com.fjec.common.protocol.JsonResult;
import com.fjec.common.util.Base64Util;
import com.fjec.common.util.DateUtil;
import com.fjec.common.util.SequenceIdGenerator;
import com.fjec.devops.entity.BizYsOfflineReg;
import com.fjec.devops.mapper.BizYsOfflineRegMapper;
import com.fjec.devops.feign.BaseClient;
import com.fjec.devops.service.IBizYsOfflineRegService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjec.devops.view.YsOfflineRegVO;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.MapUtils;
import org.jxls.common.Context;
import org.jxls.util.JxlsHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 023.银盛线下进件表 服务实现类
 * </p>
 *
 * @author admin
 * @since 2020-11-23
 */
@Service
public class BizYsOfflineRegServiceImpl extends ServiceImpl<BizYsOfflineRegMapper, BizYsOfflineReg> implements IBizYsOfflineRegService {

    @Resource
    private BizYsOfflineRegMapper mapper;

    @Resource
    private BaseClient baseClient;

    @Resource
    private SequenceIdGenerator idGenerator;

    @Override
    public boolean dateIsHandled(LocalDate date) {
        QueryWrapper<BizYsOfflineReg> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("GenerateDate", date);
        int count = mapper.selectCount(queryWrapper);
        return count > 0;
    }

    @Transactional(rollbackFor = Throwable.class)
    @Override
    public void uploadExcels(LocalDate date, String dateTime, List<Map<String, Object>> dataList) throws Exception {
        Long id = idGenerator.nextId();
        // 整理数据
        List<DataSix> dataSixList = new ArrayList<>();
        List<DataFour> dataFourList = new ArrayList<>();
        for (Map<String, Object> data : dataList) {
            String custType = MapUtils.getString(data, "custType");
            String custName = MapUtils.getString(data, "custName");
            String userCode = MapUtils.getString(data, "userCode");
            String busLicense = MapUtils.getString(data, "busLicense");
            String legalName = MapUtils.getString(data, "legalName");
            String legalCertNo = MapUtils.getString(data, "legalCertNo");
            String companyAddr = MapUtils.getString(data, "companyAddr");
            String bankTelephoneNo = MapUtils.getString(data, "bankTelephoneNo");

            if (StringUtils.equals(custType, "O")) {
                // 小微
                // 6
                DataSix dataSix = new DataSix(custName, "", userCode);
                dataSixList.add(dataSix);
                // 4
                DataFour dataFour = new DataFour(
                        userCode,
                        custName,
                        legalCertNo,
                        bankTelephoneNo,
                        companyAddr,
                        busLicense
                );
                dataFourList.add(dataFour);
            } else if (StringUtils.equals(custType, "B")) {
                // 企业
                // 6
                DataSix dataSix = new DataSix(custName, custName, userCode);
                dataSixList.add(dataSix);
                // 4
                DataFour dataFour = new DataFour(
                        userCode,
                        legalName,
                        legalCertNo,
                        bankTelephoneNo,
                        companyAddr,
                        busLicense
                );
                dataFourList.add(dataFour);
            }
        }
        // 生成excel
        byte[] file = new byte[0];
        Long annexId4 = 0L;
        Long annexId6 = 0L;
        Map<String, Object> tmpMap;
        // 4
        try (InputStream is = this.getClass().getResourceAsStream("/excelTemplate/template_4.xlsx")) {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            Context context = new Context();
            context.putVar("dataList", dataFourList);
            JxlsHelper.getInstance().processTemplate(is, bos, context);
            file = bos.toByteArray();
            tmpMap = baseClient.base64Upload(
                    Base64Util.encode(file),
                    Const.YS_OFF_LINE_REG_4.replace("{0}", dateTime),
                    111,
                    id,
                    0
            );
            annexId4 = MapUtils.getLong(tmpMap, "id");
//                FileUtils.writeByteArrayToFile(new File(String.format("D:\\%s_4.xlsx", dateTime)), file);
        }
        // 6
        try (InputStream is = this.getClass().getResourceAsStream("/excelTemplate/template_6.xlsx")) {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            Context context = new Context();
            context.putVar("dataList", dataSixList);
            JxlsHelper.getInstance().processTemplate(is, bos, context);
            file = bos.toByteArray();
            tmpMap = baseClient.base64Upload(
                    Base64Util.encode(file),
                    Const.YS_OFF_LINE_REG_6.replace("{0}", dateTime),
                    112,
                    id,
                    0
            );
            annexId6 = MapUtils.getLong(tmpMap, "id");
//                FileUtils.writeByteArrayToFile(new File(String.format("D:\\%s_6.xlsx", dateTime)), file);

        }
        if (annexId4 != 0 && annexId6 != 0) {
            // 保存数据
            BizYsOfflineReg entity = new BizYsOfflineReg();
            entity.setId(id);
            entity.setFile1Id(annexId4);
            entity.setFile2Id(annexId6);
            entity.setGenerateDate(date);
            entity.setHandled(0);
            entity.setCreateTime(DateUtil.nowLdt());
            mapper.insert(entity);
        } else {
            throw new BizException(EnumSysCode.ERR_3025.getCode(), EnumSysCode.ERR_3025.getMsg());
        }
    }

    @Override
    public JsonResult getEntityListPage(Page page) throws Exception {
        QueryWrapper<BizYsOfflineReg> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("GenerateDate");
        Page<BizYsOfflineReg> returnPage = mapper.selectPage(page, queryWrapper);
        List<YsOfflineRegVO> resultList = new ArrayList<>();
        for (BizYsOfflineReg entity : returnPage.getRecords()) {
            YsOfflineRegVO view = new YsOfflineRegVO();
            BeanUtils.copyProperties(view, entity);
            view.setHandledFile1((entity.getHandled() & 1) == 1);
            view.setHandledFile2((entity.getHandled() & 2) == 2);
            resultList.add(view);
        }
        return JsonResult.success()
                .total(returnPage.getTotal())
                .data(resultList)
                .build();
    }

    @Override
    public void downloadYsOfflineExcel(Long id, Long downloadId, Integer type, HttpServletResponse res) throws Exception {
        BizYsOfflineReg entity = mapper.selectById(id);
        if (entity != null) {
            // 更新下载状态
            if (type == 1) {
                if ((entity.getHandled() & 1) != 1) {
                    entity.setHandled(entity.getHandled() + 1);
                    entity.setUpdateTime(DateUtil.nowLdt());
                    mapper.updateById(entity);
                }
            } else if (type == 2) {
                if ((entity.getHandled() & 2) != 2) {
                    entity.setHandled(entity.getHandled() + 2);
                    entity.setUpdateTime(DateUtil.nowLdt());
                    mapper.updateById(entity);
                }
            }
            // rpc下载文件
            Map<String, Object> map = baseClient.getOSSFileBase64ById(downloadId);
            if (map != null && !map.isEmpty()) {
                String fileName = MapUtils.getString(map, "fileName");
                String base64 = MapUtils.getString(map, "base64");
                byte[] bytes = Base64Util.decode2Bytes(base64);
                res.reset();
                res.setContentType("application/octet-stream");
                res.addHeader("filename", URLEncoder.encode(fileName, "UTF-8"));
                res.addHeader("Access-Control-Expose-Headers", "filename");
                OutputStream out = res.getOutputStream();
                out.write(bytes, 0, bytes.length);
                out.flush();
            }
        }
    }
}
